package com.winai.launcher.manager;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;

import com.baidu.location.BDLocation;
import com.clj.fastble.BleManager;
import com.ks.projectbasictools.retrofit.HttpResponseListener;
import com.ks.projectbasictools.utils.LogUtils;
import com.winai.launcher.base.db.DB_Common;
import com.winai.launcher.bean.db.CurrentLocation;
import com.winai.launcher.bean.db.Device;
import com.winai.launcher.bean.requestBean.DeviceInfoBean;
import com.winai.launcher.bean.responseEntity.DeviceInfoEntity;
import com.winai.launcher.constant.HttpUrls;
import com.winai.launcher.utils.BaseUtils;
import com.winai.launcher.utils.ServerUtils;

import static com.winai.launcher.utils.BaseUtils.getMac;

/**
 * 作者：康少
 * 时间：2020/4/1 0001
 * 说明：设备信息管理器
 */
public class DeviceInfoManager {
    private final String TAG = "DeviceInfoManager";
    private Context mContext;
    private static DeviceInfoManager mInstance = null;
    private Device mDevice;

    public DeviceInfoManager() {
        try {
            throw new Exception("DeviceInfoManager不能被实例化");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private DeviceInfoManager(Context context) {
        mContext = context;
        Device device = DeviceManager.loadDeviceFromDB(BaseUtils.getDeviceId());
        if (device != null) {
            mDevice = device;
        } else {
            mDevice = new Device();
            //获取设备SN码
            mDevice.setDeviceSNCode(BaseUtils.getDeviceSN());
            //获取设备名称
            mDevice.setDeviceName(BaseUtils.getDeviceName());
            //获取设备型号
            mDevice.setDeviceType(BaseUtils.getDeviceType());
            //获取设备版本号
            mDevice.setDeviceVersion(BaseUtils.getSystemVersion());
            //获取设备Id
            mDevice.setDeviceId(BaseUtils.getDeviceId());
//            //获取上次设备地址
//            CurrentLocation last = LitePal.findLast(CurrentLocation.class);
//            if (last != null) {
//                mDevice.setAddress(last.getCity());
//            }
        }
        //获取地址
        myLocation(false);
    }

    private void myLocation(boolean isUpdate) {
        BdLocationManager.getInstance().onStart(location -> {
            if (location == null) {
                Log.e(TAG, "获取位置失败，当前信息可能有误");
                return;
            }
            if (location.getLocType() == BDLocation.TypeCriteriaException) {
                Log.e(TAG, "获取位置失败，当前信息可能有误");
            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
                Log.e(TAG, "获取位置失败，当前信息可能有误");
            } else {
                double latitude = location.getLatitude();
                double longitude = location.getLongitude();
                if (latitude == 0 || longitude == 0
                        || latitude == 4.9E-324 || longitude == 4.9E-324) {
                    Log.e(TAG, "获取位置失败，当前信息可能有误");
                    return;
                }
                String city = !TextUtils.isEmpty(location.getAddress().city)
                        ? location.getAddress().city
                        : "";
                String province = location.getAddress().province == null
                        ? city.replace("市", "")
                        : location.getAddress().province;
                String district = location.getAddress().district;

                if (!TextUtils.isEmpty(province) && !TextUtils.isEmpty(city)) {
                    mDevice.setAddress(province + "-" + city);
                } else {
                    mDevice.setAddress(null);
                }
                if (isUpdate) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            pushService();
                        }
                    }).start();
                }
                //获取经纬度位置信息，存入本地数据库缓存
                CurrentLocation currentLocation1 = new CurrentLocation();
                currentLocation1.setLatitude(latitude);
                currentLocation1.setLongitude(longitude);
                currentLocation1.setAdminArea(province);
                currentLocation1.setLocality(city);
                currentLocation1.setSubLocality(district);
                currentLocation1.saveOrUpdate("id = 1");
            }
        });
    }

    public static synchronized DeviceInfoManager getInstance(Context mContext) {
        if (mInstance == null) {
            synchronized (DeviceInfoManager.class) {
                if (null == mInstance) {
                    mInstance = new DeviceInfoManager(mContext);
                }
            }
        }
        return mInstance;
    }


    /**
     * 说明：更新最近绑定
     */
    public void updateBind(String bindTime, String userAccount) {
        DB_Common dbCommon = new DB_Common(mContext);
        dbCommon.add("isBind", "true");
        mDevice.setUserAccount(userAccount);
        mDevice.setBindStatus(true);
        mDevice.setActivateStatus(true);
        mDevice.setRecentBindTime(bindTime);
        mDevice.setRecentActivateTime(bindTime);
        pushService();
    }

    /**
     * 说明：更新最近解绑
     */
    public void updateUnbind() {
        DB_Common dbCommon = new DB_Common(mContext);
        dbCommon.add("isBind", "false");
        mDevice.setUserAccount("");
        mDevice.setBindStatus(false);
        new Thread(new Runnable() {
            @Override
            public void run() {
                pushService();
            }
        }).start();
    }

    /**
     * 说明：首次绑定和激活
     */
    public void firstBindAndActivate(boolean bindStatus, String bindTime, boolean activateStatus, String userAccount) {
        DB_Common dbCommon = new DB_Common(mContext);
        dbCommon.add("isBind", String.valueOf(bindStatus));
        mDevice.setUserAccount(userAccount);
        mDevice.setActivateAccount(userAccount);
        mDevice.setBindStatus(bindStatus);
        mDevice.setActivateStatus(activateStatus);
        mDevice.setBindTime(bindTime);
        mDevice.setActivateTime(bindTime);
        mDevice.setRecentBindTime(bindTime);
        mDevice.setRecentActivateTime(bindTime);
        mDevice.setUpdateTime(bindTime);
        new Thread(new Runnable() {
            @Override
            public void run() {
                pushService();
            }
        }).start();
    }

    /**
     * 说明：更新升级版本
     */
    public void upgradeVersion(String updateTime) {
        mDevice.setUpdateTime(updateTime);
        mDevice.setDeviceVersion(BaseUtils.getSystemVersion());
        new Thread(new Runnable() {
            @Override
            public void run() {
                pushService();
            }
        }).start();
    }

    /**
     * 说明：更新设备状态
     */
    public void updateDeviceStatus(Device.DeviceStatus deviceStatus) {
        mDevice.setDeviceStatus(deviceStatus);
        new Thread(new Runnable() {
            @Override
            public void run() {
                pushService();
            }
        }).start();
    }

    /**
     * 说明：更换了Wifi连接
     */
    public void updateWifiInfo() {
        //获取Mac地址
//        deviceId = BaseUtils.getDeviceId();
        //获取地址
        myLocation(true);
    }

    /**
     * 说明：推送服务器
     */
    @SuppressLint("HandlerLeak")
    public synchronized void pushService() {
        if (!hasChanged()) {
            LogUtils.d("设备信息无变化，不推送服务器");
            return;
        } else {
            LogUtils.d("设备信息有变化，推送服务器");
        }
        DeviceInfoBean mDeviceInfoBean = new DeviceInfoBean();
        mDeviceInfoBean.setEquipmentId(mDevice.getDeviceId());
        mDeviceInfoBean.setSerialNumber(mDevice.getDeviceSNCode());
        mDeviceInfoBean.setEquipmentName(mDevice.getDeviceName());//设备名称
        mDeviceInfoBean.setUserAccount(mDevice.getUserAccount());
        mDeviceInfoBean.setDefaultName(mDevice.getDeviceName());//默认名称
        mDeviceInfoBean.setEquipmentType(mDevice.getDeviceType());//设备类型
        mDeviceInfoBean.setEquipmentChannel(mDevice.getDeviceChannel());//设备渠道
        switch (mDevice.getDeviceStatus()) {//设备状态
            case RUNNING://运行
                mDeviceInfoBean.setUsageState("1");
                break;
            case WAITING://待机
                mDeviceInfoBean.setUsageState("2");
                break;
            case UNKNOWN://无法获取
                mDeviceInfoBean.setUsageState("0");
                break;
        }
        switch (mDevice.getOnlineStatus()) {//在线状态
            case OFF_LINE:
                mDeviceInfoBean.setOnlineState("0");
                break;
            case ONLINE:
                mDeviceInfoBean.setOnlineState("1");
                break;
        }
        mDeviceInfoBean.setActivationState(mDevice.isActivateStatus() ? "1" : "0");//激活状态
        mDeviceInfoBean.setBindingState(mDevice.isBindStatus() ? "1" : "0");
        mDeviceInfoBean.setFirmwareVersion(BaseUtils.getSystemVersion());
        mDeviceInfoBean.setFirstActivation(mDevice.getActivateTime());
        mDeviceInfoBean.setFirstBinding(mDevice.getBindTime());//首次绑定
        mDeviceInfoBean.setRecentBinding(mDevice.getRecentBindTime());//最近绑定时间
        mDeviceInfoBean.setRecentActivation(mDevice.getRecentActivateTime());//最近激活
        mDeviceInfoBean.setRecentUpdates(mDevice.getUpdateTime());
        mDeviceInfoBean.setRegion(mDevice.getAddress());
        mDeviceInfoBean.setUserAccount(mDevice.getUserAccount());
        mDeviceInfoBean.setActivationAccount(mDevice.getActivateAccount());
        mDeviceInfoBean.setType(mDevice.getType());
        //设置版本类型
        int i = BaseUtils.getSystemVersion().indexOf("_");
        if (i == -1) {
            mDeviceInfoBean.setVersionType("Release");
        } else {
            mDeviceInfoBean.setVersionType(BaseUtils.getSystemVersion().substring(i + 1));
        }
        mDeviceInfoBean.setWifiMac(getMac());
        mDeviceInfoBean.setBluetoothMac(getBtAddressViaReflection());
        mDeviceInfoBean.setMac(getMac());
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                BaseUtils.getV4IP(new Handler() {
                    @Override
                    public void handleMessage(@NonNull Message msg) {
                        super.handleMessage(msg);
                        if (msg.what == 2020) {
                            String ip = (String) msg.obj;
                            mDeviceInfoBean.setIp(ip);
                            ServerUtils.requestJsonPost(HttpUrls.DEVICE_INFO_SAVE, null, mDeviceInfoBean
                                    , new HttpResponseListener<DeviceInfoEntity>() {
                                        @Override
                                        public void onResponse(DeviceInfoEntity var1, boolean isCache) {
                                            if (var1.isData()) {
                                                LogUtils.i("设备信息更新完成，并保存到本地数据库");
                                                DeviceManager.updateDeviceToDB(mDevice);
                                            } else {
                                                LogUtils.e("设备信息更新失败");
                                            }
                                        }
                                    });
                        }
                    }
                });
            }
        });
//                mDeviceInfoBean.setIp(getIp(wifiManager));
    }

    @SuppressLint("HardwareIds")
    private String getBtAddressViaReflection() {
        BleManager.getInstance().enableBluetooth();
        while (!BleManager.getInstance().isBlueEnable()) {
            try {
                LogUtils.d("等待打开蓝牙");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        String bluetooth_address = Settings.Secure.getString(mContext.getContentResolver(), "bluetooth_address");
        LogUtils.d("获取的蓝牙Mac：" + bluetooth_address);
        BleManager.getInstance().disableBluetooth();
        return bluetooth_address;
    }

    /**
     * @date 2021/2/6
     * @desc 设备信息是否变化
     */
    private boolean hasChanged() {
        Device device = DeviceManager.loadDeviceFromDB(BaseUtils.getDeviceId());//从本地取出设备缓存
        if (device == null)
            return true;
        if (mDevice.getDeviceName() != null && !mDevice.getDeviceName().equals(device.getDeviceName()))
            return true;
        if (mDevice.getDeviceId() != null && !mDevice.getDeviceId().equals(device.getDeviceId()))
            return true;
        if (mDevice.getDeviceSNCode() != null && !mDevice.getDeviceSNCode().equals(device.getDeviceSNCode()))
            return true;
        if (mDevice.getUserAccount() != null && !mDevice.getUserAccount().equals(device.getUserAccount()))
            return true;
        if (mDevice.getActivateAccount() != null && !mDevice.getActivateAccount().equals(device.getActivateAccount()))
            return true;
        if (mDevice.getDeviceType() != null && !mDevice.getDeviceType().equals(device.getDeviceType()))
            return true;
        if (mDevice.getDeviceStatus() != null && !mDevice.getDeviceStatus().equals(device.getDeviceStatus()))
            return true;
        if (mDevice.getOnlineStatus() != null && !mDevice.getOnlineStatus().equals(device.getOnlineStatus()))
            return true;
        if (mDevice.isActivateStatus() != device.isActivateStatus())
            return true;
        if (mDevice.isBindStatus() != device.isBindStatus())
            return true;
//        if (mDevice.getDeviceVersion() != null && !mDevice.getDeviceVersion().equals(device.getDeviceVersion()))
//            return true;
        if (mDevice.getActivateTime() != null && !mDevice.getActivateTime().equals(device.getActivateTime()))
            return true;
        if (mDevice.getRecentActivateTime() != null && !mDevice.getRecentActivateTime().equals(device.getRecentActivateTime()))
            return true;
        if (mDevice.getBindTime() != null && !mDevice.getBindTime().equals(device.getBindTime()))
            return true;
        if (mDevice.getRecentBindTime() != null && !mDevice.getRecentBindTime().equals(device.getRecentBindTime()))
            return true;
        if (mDevice.getUpdateTime() != null && !mDevice.getUpdateTime().equals(device.getUpdateTime()))
            return true;
        if (mDevice.getAddress() != null && !mDevice.getAddress().equals(device.getAddress()))
            return true;
        if (mDevice.getType() != null && !mDevice.getType().equals(device.getType()))
            return true;
        if (mDevice.getDeviceChannel() != null && !mDevice.getDeviceChannel().equals(device.getDeviceChannel()))
            return true;
        return false;
    }

    public Device getDevice() {
        return mDevice;
    }
}
